package org.papillion39.sechelper.application.business;

import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.InvalidKeySpecException;
import java.util.Arrays;

import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;

/**
 *
 * @author Jonathan Paz <jonathan.paz@ottr.com>
 */
public final class Utils {
    private static final SecretKeyFactory fac;
    private static final SecureRandom random = new SecureRandom();
    static {
        try {
            fac = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("Standard algorithm does not exist. Something's very wrong.", e);
        }
    }
    private Utils() {
        throw new UnsupportedOperationException("Instantiating Utils not allowed.");
    }

    public static final class SaltedHash {
        public final byte[] hash;
        public final byte[] salt;
        private SaltedHash(byte[] hash, byte[] salt) {
            this.hash = hash;
            this.salt = salt;
        }
    }

    public static SaltedHash generatePasswordHash(char[] password) {
        byte[] salt = new byte[32];
        random.nextBytes(salt);
        PBEKeySpec spec = new PBEKeySpec(password, salt, 4096, 256);
        Arrays.fill(password, '\0');
        try {
            SecretKey generateSecret = fac.generateSecret(spec);
            spec.clearPassword();
            return new SaltedHash(generateSecret.getEncoded(),salt);
        } catch (InvalidKeySpecException e) {
            throw new RuntimeException("PBE factory doesn't accept PBE key spec. Something's very wrong.", e);
        }
    }
}
